package forestsimulatorp3.model.simulator;

import forestsimulatorp3.model.beings.Environment;
import forestsimulatorp3.model.beings.Forest;
import java.util.HashSet;
import java.util.Set;
import forestsimulatorp3.model.beings.abstrakt.LivingBeing;
import forestsimulatorp3.model.beings.Squirrel;
import forestsimulatorp3.model.position.Area;
import model.enums.Gender;
import model.enums.Season;
import model.enums.Weather;
import forestsimulatorp3.model.position.Square;
import forestsimulatorp3.view.MainWindow;

/**
 * The simulator of the forest. Contains the main function
 * @author dielson
 *
 */
public class ForestSimulator {

    Season currentSeason;
    Weather currentWeather;
    Environment environment;
    MainWindow parent;
    Logger logger;

    // Constructors ------------------------------------------------------------
    public ForestSimulator(MainWindow parent) {
        this.parent = parent;
        environment = new Forest();
        environment.setLivingBeings(getReadyAnimals(environment.getArea()));

        logger = new Logger(this.parent);
        environment.setLogger(logger);
    }

    // Public methods ----------------------------------------------------------
    public void executeCycles(long cycles) {
        for (int i = 0; i < cycles; i++) {
            advanceForestCycle();
        }
    }

    // Private methods ---------------------------------------------------------
    /**
     * Puts all the forest in execution.
     */
    private void advanceForestCycle() {
        Time.advanceForestCycle();
        verifySeason();

        WeatherController.advanceCycle();
        verifyWeather();

        environment.advanceCycle();
        parent.notifyAction("Lá vai um ciclo!");
    }

    private void verifySeason() {
        if (!Time.getCurrentSeason().equals(currentSeason)) {
            currentSeason = Time.getCurrentSeason();
            parent.notifyAction("Estação mudou. Nova estação do ano: " + currentSeason);
        }
    }

    private void verifyWeather() {
        if (!WeatherController.getCurrentWeather().equals(currentWeather)) {
            currentWeather = WeatherController.getCurrentWeather();
            parent.notifyAction("Tempo mudou. Previsão: " + currentWeather
                    + " por " + (WeatherController.getTimeUntilNextWeather() + 1)
                    + " ciclos");
        }
    }

    private Set<LivingBeing> getReadyAnimals(Area area) {
        //TODO: incomplete
        Set<LivingBeing> livingBeings = new HashSet<LivingBeing>();
        for (int i = 0; i < 10; i++) {
            livingBeings.add(new Squirrel(environment.getNextAvailableId(), Gender.MALE, environment, area.getSquareInstance(i * 5, i * 7)));
        }
        return livingBeings;
    }
}
